package com.gopay.cashier.web.controller;

import java.math.BigDecimal;
import java.security.interfaces.RSAPublicKey;
import java.text.DecimalFormat;
import java.util.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import com.gopay.cashier.web.command.PayChannelCommand;
import com.gopay.cashier.web.command.PayInfoCommand;
import com.gopay.cashier.web.utils.HexStringByte;
import com.gopay.cashier.web.utils.RSAUtil4js;
import com.gopay.common.constants.SubAccountConstants;
import com.gopay.common.constants.dic.SchemaCode;
import com.gopay.common.core.dic.manager.AcpsSchemaAcctRelQueryManager;
import com.gopay.common.cps.dao.order.CpsGeneralReceiptOrderQueryDAO;
import com.gopay.common.cps.dao.trans.CpsReceiptSplitDtlQueryDAO;
import com.gopay.common.domain.UserInfo;
import com.gopay.common.domain.cps.CpsGenReceiptOrder;
import com.gopay.common.domain.cps.CpsReceiptSplitDtl;
import com.gopay.common.domain.user.PwdCtrlAttrInfo;
import com.gopay.common.user.manager.PwdCtrlAttrInfoManager;
import com.gopay.common.util.JsonUtils;
import ocx.AESWithJCE;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.shiro.SecurityUtils;
import org.bouncycastle.util.encoders.Base64;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.multiaction.MultiActionController;

import com.gopay.cashier.common.exception.WebException;
import com.gopay.cashier.domain.bean.AcctBean;
import com.gopay.cashier.domain.bean.LoginUser;
import com.gopay.cashier.service.B2BBankConfigService;
import com.gopay.cashier.service.BisBankInfoService;
import com.gopay.cashier.service.CustCorpInfoService;
import com.gopay.cashier.service.SoluBisPayChannelService;
import com.gopay.cashier.service.TransLimitCheckService;
import com.gopay.cashier.service.UserInfoService;
import com.gopay.cashier.web.command.BankPayChannelCommand;
import com.gopay.cashier.web.command.OrderInfo;
import com.gopay.cashier.web.utils.CashierConfig;
import com.gopay.cashier.web.utils.DigestUtil;
import com.gopay.common.cipher.utils.LoggerMaskUtils;
import com.gopay.common.constants.YnFlag;
import com.gopay.common.constants.cps.ChildTranType;
import com.gopay.common.constants.cust.CustCorpInfoConstants;
import com.gopay.common.constants.cust.CustPersonInfoConstants;
import com.gopay.common.constants.proccode.ProcCodeConstants;
import com.gopay.common.constants.rcs.TranDirection;
import com.gopay.common.constants.rims.RimsEvaluateResultStatus;
import com.gopay.common.constants.trans.GatewayChannel;
import com.gopay.common.constants.trans.GatewaySource;
import com.gopay.common.constants.trans.MerCommPayer;
import com.gopay.common.constants.trans.OrderFeePayer;
import com.gopay.common.constants.trans.PayChannel;
import com.gopay.common.constants.trans.TxnStaCode;
import com.gopay.common.constants.txncd.IntTxnCd;
import com.gopay.common.cps.dao.gp.CpsGpContractInfoDAO;
import com.gopay.common.cps.dao.order.CpsGeneralMainOrderQueryDAO;
import com.gopay.common.cps.manager.CpsAcctProdMastQueryManager;
import com.gopay.common.cps.manager.order.CpsGeneralMainOrderQueryManager;
import com.gopay.common.cps.manager.order.FullCpsGenRecvOrderQueryManager;
import com.gopay.common.domain.acps.AcctProd;
import com.gopay.common.domain.acps.model.AcctMastBean;
import com.gopay.common.domain.bis.BisBankInfoMain;
import com.gopay.common.domain.cps.CpsAcctProdMast;
import com.gopay.common.domain.cps.CpsGenMainOrder;
import com.gopay.common.domain.cps.gp.CpsGpContractInfo;
import com.gopay.common.domain.cust.CustCorpInfo;
import com.gopay.common.domain.cust.CustPersonInfo;
import com.gopay.common.domain.gopay.GopayAllCustInfo;
import com.gopay.common.domain.poundage.PoundageReq;
import com.gopay.common.domain.poundage.PoundageRes;
import com.gopay.common.domain.rims.RimsEvaluateParas;
import com.gopay.common.domain.rims.RimsEvaluateResult;
import com.gopay.common.domain.rims.RimsEvaluateParas.ParaKey;
import com.gopay.common.domain.solution.LegalObjReq;
import com.gopay.common.domain.solution.LegalObjRes;
import com.gopay.common.domain.solution.SolutionRequest;
import com.gopay.common.domain.solution.SolutionResponse;
import com.gopay.common.exception.GopayException;
import com.gopay.common.gateway.manager.PgBTOrderTransDtlQueryManager;
import com.gopay.common.gateway.manager.PgGeneralOrderTransDtlQueryManager;
import com.gopay.common.gateway.manager.PgP2pOrderTransDtlQueryManager;
import com.gopay.common.proccode.DicProcCodeService;
import com.gopay.common.rcs.bean.VerifyCodeCheckStatus;
import com.gopay.common.rcs.manager.antiphish.RcsAntiPhishingViolateLogManager;
import com.gopay.common.rcs.service.antiphish.check.RcsAntiPhishingCheckService;
import com.gopay.common.rcs.service.rims.RimsTransService;
import com.gopay.common.user.dao.AllCustInfoQueryDAO;
import com.gopay.common.user.manager.CustPersonInfoQueryManager;
import com.gopay.common.user.manager.UserDcPwdManager;
import com.gopay.common.user.manager.UserPayPwdManager;
import com.gopay.common.util.DateUtils;
import com.gopay.common.util.RequestUtils;
import com.gopay.remote.acps.service.AcctTransRemoteService;
import com.gopay.remote.cps.cashier.CashierPayCallbackRemoteService;
import com.gopay.remote.cps.poundage.PoundageRemoteService;
import com.gopay.remote.cps.rims.RimsRemoteService;
import com.gopay.remote.order.MainOrderField;
import com.gopay.remote.order.MainOrderUpdateRemoteService;
import com.gopay.remote.solution.SolutionRemoteService;
import com.gopay.remote.user.UserRemoteService;

public abstract class BaseController extends MultiActionController {
	protected final static Log logger = LogFactory.getLog("CASHIER-LOG");
	/** 是否禁用图片验证码 true:是；false:否 */
	protected static final boolean IS_CAPTCHA_DISABLED = CashierConfig.getBool(CashierConfig.IS_CAPTCHA_DISABLED);
	@Resource(name="cpsGeneralMainOrderQueryDAO")
    protected CpsGeneralMainOrderQueryDAO cpsGeneralMainOrderQueryDAO;
	@Autowired
	protected CustCorpInfoService custCorpInfoService;
	@Resource(name = "custPersonInfoQueryManager")
	protected CustPersonInfoQueryManager custPersonInfoQueryManager;
	@Autowired
	protected AcctTransRemoteService acctTransService;

	@Autowired
	private CpsGeneralReceiptOrderQueryDAO cpsGeneralReceiptOrderQueryDAO;

	@Autowired
	private CpsReceiptSplitDtlQueryDAO cpsReceiptSplitDtlQueryDAO;

	@Resource(name = "cashierPayCallbackService")
	protected CashierPayCallbackRemoteService cashierPayCallbackService;
	@Resource(name = "mainOrderUpdateService")
	protected MainOrderUpdateRemoteService mainOrderUpdateService;
	@Autowired
	protected DicProcCodeService dicProcCodeService;
	@Autowired
	protected BisBankInfoService bisBankInfoService;
	@Autowired
	protected UserInfoService userInfoService;
	@Resource(name = "uiConfigService")
	protected SolutionRemoteService uiConfigService;
	@Resource(name = "transPayChanService")
	protected SolutionRemoteService transPayChanService;
	@Autowired
	protected FullCpsGenRecvOrderQueryManager fullCpsGenRecvOrderQueryManager;
	@Resource(name = "poundageService")
	protected PoundageRemoteService poundageService;
	@Resource(name = "pgGeneralOrderTransDtlQueryManager")
	protected PgGeneralOrderTransDtlQueryManager pgGeneralOrderTransDtlQueryManager;
	@Resource(name = "pgBTOrderTransDtlQueryManager")
	protected PgBTOrderTransDtlQueryManager pgBTOrderTransDtlQueryManager;
	@Resource(name = "userPayPwdManager")
	protected UserPayPwdManager userPayPwdManager;
	@Resource(name = "cpsAcctProdMastQueryManager")
	protected CpsAcctProdMastQueryManager cpsAcctProdMastQueryManager;

	@Autowired
	protected RcsAntiPhishingCheckService rcsAntiPhishingCheckService;
	@Autowired
	protected RcsAntiPhishingViolateLogManager rcsAntiPhishingViolateLogManager;
	@Resource(name = "legalObjSolutionClient")
	protected SolutionRemoteService legalObjSolutionClient;
	@Resource(name = "allCustInfoQueryDAO")
	protected AllCustInfoQueryDAO allCustInfoQueryDAO;
    
    @Autowired
    protected SoluBisPayChannelService soluBisPayChannelService;

    @Resource(name = "rimsService")
    protected RimsRemoteService rimsRemoteService;
    @Autowired
    protected RimsTransService rimsTransService;
    /**
     * p2p签约协议
     */
    @Resource(name = "cpsGpContractInfoDAO")
    protected CpsGpContractInfoDAO cpsGpContractInfoDAO;

    @Resource(name = "transLimitCheckService")
    protected TransLimitCheckService transLimitCheckService;

    /**
     * p2p网关流水
     */
    @Resource(name="pgP2pOrderTransDtlQueryManager")
    protected PgP2pOrderTransDtlQueryManager pgP2pOrderTransDtlQueryManager;

    /**
     * B2B 银行配置
     */
    @Resource(name = "b2bBankConfigService")
    protected  B2BBankConfigService b2bBankConfigService;

    /**
     * 远程用户注册接口
     */
    @Resource(name = "userRemoteService")
    protected UserRemoteService userRemoteService;
    
    @Resource(name = "cpsGeneralMainOrderQueryManager")
    protected CpsGeneralMainOrderQueryManager cpsGeneralMainOrderQueryManager;
    
    @Resource(name = "userDcPwdManager")
    protected UserDcPwdManager userDcPwdManager;

	@Autowired
	private PwdCtrlAttrInfoManager pwdCtrlAttrInfoManager;

	@Autowired
    private AcpsSchemaAcctRelQueryManager acpsSchemaAcctRelQueryManager;

	/****************************** Session ************************************/
	/** Session-保存图片验证码 */
	public static final String KEY_CAPTCHA = "key_captcha";
	/** Session-保存反钓鱼图片验证码 */
	public static final String KEY_ANTIPHISH_VERIFYCODE = "key_antiphish_verifycode";
	/** 支付密码验证，一次一密，服务端随机码 */
	public static final String KEY_SEC_CODE = "key_sec_code";
	/** 表单随机码formhash，防止构造表单，hack流程 */
	public static final String KEY_FORM_HASH = "key_form_hash";
	/** 登录用户 */
	public static final String KEY_LOGIN_USER = "key_login_user";

	/****************************** 页面 ************************************/
	/** 页面 - 提示页面 */
	public static final String VIEW_MESSAGE = "common/message";
	/** 页面 - 错误页面 */
	public static final String VIEW_ERROR = "common/error";

	/****************************** 字段 ************************************/
	/** 字段 - 错误代码 */
	public static final String FIELD_ERR_CODE = "err_code";
	/** 字段 - 错误详细信息 */
	public static final String FIELD_ERR_MSG = "err_msg";
	/** 字段 - 提示页面标题 */
	public static final String FIELD_MSG_TITLE = "msg_title";
	/** 字段 - 提示页面摘要信息 */
	public static final String FIELD_MSG_SUMMARY = "msg_summary";
	/** 字段 - 提示页面详细信息 */
	public static final String FIELD_MSG_DETAIL = "msg_detail";

	/** 字段 - portal指定充值交易 标识 */
	public static final String FIELD_INC = "inc";
	/** 字段 - 指定CAS登录用户名 */
	public static final String FIELD_U = "u";

	
	public static final String CAS_GOPAY_USER = "gopayUser";
	
	public static final String GOPAY_ORDER_ID = "orderId";
	public static final String GOPAY_ORDER_KEY = "orderKey";


	@Value("#{webProperties['certLicense']}")
	private String certLicense ;



	protected void prepareRSA() throws Exception {
		RSAPublicKey rsap = (RSAPublicKey) RSAUtil4js.getKeyPair().getPublic();
		String module = rsap.getModulus().toString(16);
		String empoent = rsap.getPublicExponent().toString(16);
		getRequest().setAttribute("module", module);
		getRequest().setAttribute("empoent", empoent);
	}

	/**
	 * 全局错误处理
	 */
	@ExceptionHandler({ Exception.class })
	public String handleException(HttpServletRequest request, Exception e) {
		/**
		 * modified by zyt 日志中可能出现卡号处做掩码显示
		 * 2017-3-22
		 */
		logger.error("sys-ex:" + request.getHeader("Referer") + ";" + clientIp(request) + ";" + LoggerMaskUtils.maskString(getReqPara(request).toString()), e);
		String code = "-";
		String msg = "-";
		if (e instanceof GopayException) {
			code = ((GopayException) e).getErrCode();
			msg = dicProcCodeService.getProcCodeInfo(code).getMessage();
			//如果自定义的异常串，包含库里存储的异常串，则显示自定义异常串，否显示两个用逗号隔开 modifyby liuyong
			String errorMsg = ((GopayException) e).getErrMsg();
			if(errorMsg!=null&&errorMsg.contains(msg)){
				msg = errorMsg;
			}else{
				if(errorMsg!=null&&!"".equals(errorMsg)){
					msg = msg +","+errorMsg;
				}
			}

			if (StringUtils.isBlank(code)) {
				code = "-";
				if (StringUtils.isNotBlank(((GopayException) e).getErrMsg())) {
					msg = ((GopayException) e).getErrMsg();
				}
			}

		} else {
			msg = e.getMessage();
			// 如果没有异常信息，显示默认异常信息。
			if (StringUtils.isBlank(msg)) {
				msg = dicProcCodeService.getProcCodeInfo(ProcCodeConstants.PROC_CODE_100F1002).getMessage();
			}
		}
		request.setAttribute(FIELD_ERR_CODE, code);
		request.setAttribute(FIELD_ERR_MSG, msg);
		return VIEW_ERROR;
	}

	public LoginUser getLoginUser(){
		LoginUser lu = (LoginUser)SecurityUtils.getSubject().getPrincipal();
		return lu;
	}
	/**
	 * 验证图片验证码
	 * 
	 * @param request
	 * @param captcha
	 * @return
	 */
	public static boolean validateCaptcha(HttpServletRequest request, String captcha) {
		if (IS_CAPTCHA_DISABLED) {
			return true;
		}
		String captchaInSession = (String) request.getSession().getAttribute(KEY_CAPTCHA);
		// 重置session中的验证码
		request.getSession().setAttribute(KEY_CAPTCHA, null);
		if (null == captchaInSession) {
			logger.error("captchaInSession = null !!");
			return false;
		}
		if (!captchaInSession.equalsIgnoreCase(captcha)) {
			return false;
		}
		return true;
	}

	/**
	 * 校验收款方客户状态.<br>
	 * 企业客户/个人客户都有可能。<br>
	 * custType: 0-未知； 1-个人； 2-企业 ；
	 * 
	 * @throws WebException
	 */
	protected void checkRecvCustStatus(int custType, String custId) throws WebException {
		// 企业客户
		CustCorpInfo corpInfo = null;
		if (0 == custType || 2 == custType) {
			corpInfo = custCorpInfoService.get(custId);
		}
		// 个人用户
		CustPersonInfo personInfo = null;
		if (0 == custType || 1 == custType) {
			personInfo = custPersonInfoQueryManager.get(custId);
		}
		if (null != corpInfo) {
			String stat = corpInfo.getCorpStat();
			if (CustCorpInfoConstants.CORP_STAT_CANCEL.equals(stat)) {
				throw new WebException(ProcCodeConstants.PROC_CODE_100E5001);
			}
			// 企业状态异常
			if (!CustCorpInfoConstants.CORP_STAT_NORMAL.equals(stat)) {
				throw new WebException(ProcCodeConstants.PROC_CODE_100E2028);
			}
		} else if (null != personInfo) {
			String stat = personInfo.getCustStat();
			if (CustPersonInfoConstants.CUST_STAT_CANCEL.equals(stat)) {
				throw new WebException(ProcCodeConstants.PROC_CODE_100E5001);
			}
			if (!CustPersonInfoConstants.CUST_STAT_NORMAL.equals(stat)) {
				throw new WebException(ProcCodeConstants.PROC_CODE_100E5002);
			}
		} else {
			// 用户不存在
			throw new WebException(ProcCodeConstants.PROC_CODE_100E5001);
		}
	}

	protected boolean hideIndivBank(CpsGenMainOrder order) {
		// 只有 企业用户 发起的 充值交易才隐藏个人银行图标。
		if (!IntTxnCd._00500.value.equals(order.getGopayIntTxnCd())) return false;
		String acct = order.getMainRecvAcct();
		// TODO tmp
		if (StringUtils.isBlank(acct) && 19 != acct.length()) return false;
		if (StringUtils.equals("2", "" + acct.charAt(9))) return true;
		else
			return false;
	}

	protected String clientIp(HttpServletRequest request) {
		return RequestUtils.getRemoteRealIpAddr(request);
	}


	/**
	 * 付款类交易返回PayAcct；收款类交易返回MainRecvAcct;
	 * 
	 * @throws WebException
	 */
	protected String getAcctId(CpsGenMainOrder order) throws WebException {
		/** 收款类 */
		if (IntTxnCd._00100.value.equals(order.getGopayIntTxnCd())) return order.getMainRecvAcct();
		else if (IntTxnCd._01813.value.equals(order.getGopayIntTxnCd())) return order.getMainRecvAcct();
		else if (IntTxnCd._00300.value.equals(order.getGopayIntTxnCd())) return order.getMainRecvAcct();
		else if (IntTxnCd._00400.value.equals(order.getGopayIntTxnCd())) return order.getMainRecvAcct();
		else if (IntTxnCd._00900.value.equals(order.getGopayIntTxnCd())) return order.getMainRecvAcct();
		else if (IntTxnCd._00500.value.equals(order.getGopayIntTxnCd())) return order.getMainRecvAcct();
		else if (IntTxnCd._00200.value.equals(order.getGopayIntTxnCd())) return order.getMainRecvAcct();
        else if (IntTxnCd._01300.value.equals(order.getGopayIntTxnCd()) || IntTxnCd._01302.value.equals(order.getGopayIntTxnCd())){
            return getP2PTrustAcctId(order);
        }
		/** 付款类 */
		logger.error("根据内部交易码获取acctId错误！" + order);
		throw new WebException(ProcCodeConstants.PROC_CODE_100E7006);
	}

    /**
     * 获取p2p交易 平台托管账户
     * @return
     */
    private String getP2PTrustAcctId(CpsGenMainOrder order) throws WebException {
        String contractNo = order.getRemark1();
        if(StringUtils.isBlank(contractNo))
            throw new WebException(ProcCodeConstants.PROC_CODE_100E7006);

        CpsGpContractInfo cpsGpContractInfo = cpsGpContractInfoDAO.getByContractNo(contractNo);
        if(cpsGpContractInfo == null)
            throw new WebException(ProcCodeConstants.PROC_CODE_100E7006);

        return cpsGpContractInfo.getTrustAcct();
    }
    /**
     * 获取p2p交易手续费
     * @param order
     * @param payChannel
     * @return
     * @throws WebException
     */
    protected PoundageRes getPoundageRes(CpsGenMainOrder order, PayChannel payChannel) throws WebException {
       return getPoundageRes(order, payChannel,null);
    }

	/**
	 * 重写获取交易手续费  jianghoup  20160908
	 * @param order
	 * @param payChannel
	 * @param bankCode
	 * @return
	 * @throws WebException
	 */
	protected PoundageRes getPoundageRes(CpsGenMainOrder order, PayChannel payChannel,String bankCode) throws WebException {
		PoundageRes res = null;
		PoundageReq req = new PoundageReq();
		if(isP2P(order)){
			CpsGpContractInfo gpContractInfo = cpsGpContractInfoDAO.getByContractNo(order.getRemark1());
			if(gpContractInfo == null){
				logger.error("can't get CpsGpContractInfo by ContractNo:"+order.getRemark1());
				throw new WebException(ProcCodeConstants.PROC_CODE_100E5051);
			}
			req.setAcctId(gpContractInfo.getTrustAcct());
		}else if(StringUtils.equals(order.getGatewaySource(), GatewaySource.GATEWAY_SOURCE_09.value)){
			//G商融通
			AcctMastBean terraceAcct = getPTAcctBean(order.getMerId());
			if(terraceAcct == null){
				throw new WebException(ProcCodeConstants.PROC_CODE_100E5276);
			}
			req.setAcctId(terraceAcct.getAcctId());
			req.setOrderFeePayer(OrderFeePayer.toValue(order.getOrderFeePayer()));
			//分账计算手续费使用原账号
		}else if(isSplit(order)){
			req.setAcctId(order.getOtherAcct());
		}else{
			req.setAcctId(order.getMainRecvAcct());
		}

		req.setAmount(order.getMerTxnAmt());
		req.setIntTxnCd(IntTxnCd.get(order.getGopayIntTxnCd()));
		req.setPayChannel(payChannel.toString());
		//增加特例银行 add by jianghoup
		logger.info("收银台{计算手续费}，订单的交易类型为："+order.getGopayIntTxnCd());
		if(StringUtils.isNotEmpty(bankCode) && IntTxnCd._00100.value.equals(order.getGopayIntTxnCd())){
			req.setBankCode(bankCode);
			logger.info("收银台{计算手续费}，设置的特例银行编码为："+bankCode);
		}

		//p2p手续费承担方是通过接口上送的
		if(isP2P(order)){
			req.setOrderFeePayer(OrderFeePayer.toValue(order.getOrderFeePayer()));
		}
		try {
			logger.info("poundage "+order.getGopayOrderId()+" calculate req:"+ToStringBuilder.reflectionToString(req, ToStringStyle.DEFAULT_STYLE));
			res = poundageService.calculate(req);
			logger.info("poundage "+order.getGopayOrderId()+" calculate res:"+ToStringBuilder.reflectionToString(res, ToStringStyle.DEFAULT_STYLE));
			//p2p交易 佣金为付方付
			if(isP2P(order) && order.getMerCommPayer()!=null && StringUtils.equals(order.getMerCommPayer(),MerCommPayer._PAY.value) && order.getMerCommAmt()!=null && order.getMerCommAmt().compareTo(new BigDecimal(0))==1){
				res.setOrderDealAmt(res.getOrderDealAmt().add(order.getMerCommAmt()));
				res.setTotalAmt(res.getTotalAmt().add(order.getMerCommAmt()));
			}
		} catch (Exception e) {
			e.printStackTrace();
			throw new WebException(ProcCodeConstants.PROC_CODE_100E5051);
		}
		return res;
	}

    protected static boolean  isP2P(CpsGenMainOrder order){
        if(order == null)
            return false;
        //p2p充值 转账
        if(StringUtils.equals(order.getGopayIntTxnCd(), IntTxnCd._01300.value) || StringUtils.equals(order.getGopayIntTxnCd(), IntTxnCd._01302.value)){
            return true;
        }
        return false;
    }


	protected boolean  isSplit(CpsGenMainOrder cpsGenMainOrder){
		if(cpsGenMainOrder != null &&acpsSchemaAcctRelQueryManager.getInnerAcct(SchemaCode.SCHEMA_CODE_2315,
				cpsGenMainOrder.getGopayIntTxnCd()).equals(cpsGenMainOrder.getMainRecvAcct())){
			return true;
		}
		return false;
	}

    protected OrderInfo getOrderInfo(String gopayOrderId) throws WebException {
        OrderInfo orderInfo = new OrderInfo();
        CpsGenMainOrder order = cpsGeneralMainOrderQueryDAO.find(CpsGenMainOrder.class, gopayOrderId);
        CustCorpInfo cust = (null == order) ? null : custCorpInfoService.get(order.getMerId());
        if (null == order) {
            logger.error("订单不存在！order not exist!" + gopayOrderId);
            throw new WebException(ProcCodeConstants.PROC_CODE_100E5041);
        }
        if (null == cust) {
            logger.error("商户不存在！cust not exist!" + gopayOrderId);
            throw new WebException(ProcCodeConstants.PROC_CODE_100E5001);
        }
        orderInfo.setMerOrderId(order.getMerOrderId());
        DecimalFormat f = new DecimalFormat("0.00");
        // 默认取订单总金额，但是订单刚提交到收银台时，此值为0（还没有计算手续费），因此收银台首页需要显示MerTxnAmt（单独处理:在调用getOrderInfo()方法后再setOrderAmt）。
        orderInfo.setOrderAmt(f.format(order.getTotalOrderAmt()));
        orderInfo.setFeeAmt(f.format(order.getTotalOrderFeeAmt()));
        orderInfo.setOrderDate(DateUtils.date2string(order.getMerTxnTm(), "yyyy-MM-dd HH:mm:ss"));
        orderInfo.setOrderId(gopayOrderId);
        orderInfo.setIntTxnCd(order.getGopayIntTxnCd());
        orderInfo.setFeePayer(order.getOrderFeePayer());
        if(order.getMerCommAmt() != null && StringUtils.equals(MerCommPayer._PAY.value,order.getMerCommPayer()))
            orderInfo.setMerCommAmt(f.format(order.getMerCommAmt()));//平台佣金
        String merName;
        // 如果是充值交易，要显示充值用户的用户名称
        if (isInchargeOrder(order) || isP2P(order)) {
            CustCorpInfo corp = custCorpInfoService.get(order.getMainRecvCustId());
            if (null == corp) {// 个人用户
                CustPersonInfo person = custPersonInfoQueryManager.get(order.getMainRecvCustId());
                if (null == person) {
                    logger.error("个人用户不存在！person not exist!" + gopayOrderId);
                    throw new WebException(ProcCodeConstants.PROC_CODE_100E5001);
                }
                if(StringUtils.equals(person.getRegType(),CustPersonInfoConstants.REG_TYPE_MOBILE)){
                    merName = person.getCustMob();
                }else{
                    merName = person.getEmail();
                }
            } else {
                if(StringUtils.equals(corp.getRegType(),CustCorpInfoConstants.REG_TYPE_MOBILE)){
                    merName = corp.getCustMob();
                }else{
                    merName = corp.getEmail();
                }
            }
        } else {
            merName = cust.getMerName();
            // 当商户名称为空时，取企业名称 兼容老用户 add by jianglijun 20171219
			if(StringUtils.isBlank(merName)) {
				merName = cust.getCorpName();
			}
        }
		orderInfo.setPayChannel(order.getPayChannel());
        orderInfo.setRecvName(merName);
        orderInfo.setMerTxnAmt(f.format(order.getMerTxnAmt()));
		//保存订单错误描述到页面 add by liuyong
		orderInfo.setErrorMsg(order.getErrMsg());
        return orderInfo;
    }
	/**
	 * 是否为充值交易；
	 */
	protected boolean isInchargeOrder(CpsGenMainOrder order) {
		// 只有内部交易码为00500且关联orderId为空的(充值交易)，才返回true。
		if (!IntTxnCd._00500.value.equals(order.getGopayIntTxnCd())) return false;
		if (StringUtils.isNotBlank(order.getRelevanceGopayOrderId())) return false;
		return true;
	}

    protected boolean isP2PInChargeOrder(CpsGenMainOrder order){
        if (!IntTxnCd._01300.value.equals(order.getGopayIntTxnCd())) return false;
        if (StringUtils.isNotBlank(order.getRelevanceGopayOrderId())) return false;
        return true;
    }

	protected BisBankInfoMain getBank(String bankCode, boolean nullException) throws WebException {
		BisBankInfoMain bi = null;
		bi = bisBankInfoService.getByCode(bankCode);
		if (nullException) {
			if (null == bi) {
				logger.error("银行不存在！bank not exist! bankCode=" + bankCode);
				throw new WebException(ProcCodeConstants.PROC_CODE_100F1002);
			} else {
				return bi;
			}
		}
		return bi;
	}

	/**
	 * 判断在发往银行前的页面是否需要用户输入支付密码。
	 */
	protected String needPaypwd(String orderId) throws WebException {
		CpsGenMainOrder order = cpsGeneralMainOrderQueryDAO.find(CpsGenMainOrder.class,orderId);
        if(order == null)
            throw new WebException(ProcCodeConstants.PROC_CODE_100E5041);
		return needPaypwd(order);
	}

	/**
	 * 判断在发往银行前的页面是否需要用户输入支付密码。
	 */
	protected String needPaypwd(final CpsGenMainOrder order) throws WebException {
		CpsGenMainOrder realOrder = getInchargeOrgOrder(order, true);

		// 充值交易的PayAcct也有值，但是充值交易不需要输入支付密码.
		if (isInchargeOrder(realOrder)) {
			return YnFlag.n.code;
		}
		// PayAcct有值表示为: 虚拟卡支付 或者 登录后虚拟卡支付
		if ((!isP2P(realOrder) && StringUtils.isNotBlank(realOrder.getPayAcct())) || (isP2P(realOrder) && (StringUtils.equals(realOrder.getPayChannel(),PayChannel._02.value)))) {
			return YnFlag.y.code;
		} else {
			return YnFlag.n.code;
		}
	}

	/**
	 * @param orderId
	 * @param nullException
	 *            - true:如果CpsGenMainOrder为null，抛出异常；false:
	 *            如果CpsGenMainOrder为null，返回null
	 * @throws WebException
	 */
	protected CpsGenMainOrder getMainOrder(String orderId,boolean nullException) throws WebException {
		CpsGenMainOrder order = null;
        String orderKey = getRequest().getParameter(GOPAY_ORDER_KEY);
		if (StringUtils.isBlank(orderId)) {
			logger.error("查询CpsGenMainOrder，订单号orderId为空！ ");
		} else {

            order = cpsGeneralMainOrderQueryDAO.find(CpsGenMainOrder.class,orderId);
            if(StringUtils.isNotBlank(orderKey) && !StringUtils.equals(orderKey,"null")){
                if(order !=null && order.getRelevanceGopayOrderId() ==null && !StringUtils.equals(getOrderKey(orderId),orderKey)){
                    logger.error(getRequest().getHeader("Referer")+">>>>  orderId:"+orderId+" has been modify!!!!!!!!!");
                    throw new WebException(ProcCodeConstants.PROC_CODE_100E5042);
                }
            }else{
                logger.error(getRequest().getHeader("Referer")+">>>> orderId:"+orderId+" orderKey is null--------------!!!!!!!!!");
            }

		}
		if (nullException) {
			if (null == order) {
				logger.error("找不到订单！order not exits! orderId=" + orderId);
				throw new WebException(ProcCodeConstants.PROC_CODE_100E5041);
			} else {
				return order;
			}
		}
		return order;
	}

    protected String getOrderKey(String orderId){
        return HexStringByte.byteToHex(DigestUtil.getDigestData(orderId.getBytes(), DigestUtil.SHA1));
    }

	/**
	 * 1.未登录网银支付，直接返回order<br>
	 * 2.登录后网银支付，根据充值订单查询原订单.<br>
	 * <br>
	 * 
	 * nullException - true：如果order是null，抛出异常； false：如果order是null，直接返回null；<br>
	 * 
	 */
	protected CpsGenMainOrder getInchargeOrgOrder(CpsGenMainOrder order, boolean nullException) throws WebException {
		if (null == order) {
			if (nullException) {
				logger.error("找不到订单！order not exits! ");
				throw new WebException(ProcCodeConstants.PROC_CODE_100E5041);
			} else {
				return null;
			}
		}
		String rId = order.getRelevanceGopayOrderId();
		if (StringUtils.isBlank(rId)) return order;
		CpsGenMainOrder orgOrder = cpsGeneralMainOrderQueryDAO.find(CpsGenMainOrder.class,rId);
		// 如果是登录后支付，应该校验原订单相关信息。
		if (null != orgOrder) return orgOrder;
		else
			return order;
	}

	/**
	 * 
	 * @param request
	 * @return 把request中的参数重新放到一个map中。<br>
	 *         request.getParameterMap()中的每个value都是一个数组，不方便使用。
	 */
	@SuppressWarnings("unchecked")
	protected static Map<String, String> getReqPara(HttpServletRequest request) {
		Map<String, String> paramMap = new HashMap<String, String>();
		Map<String, String[]> map = request.getParameterMap();
		for (Iterator<?> iter = map.entrySet().iterator(); iter.hasNext();) {
			Map.Entry<String, Object> element = (Map.Entry<String, Object>) iter.next();
			String strKey = (String) element.getKey();
			String[] value = (String[]) element.getValue();
			paramMap.put(strKey, value[0]);
		}
		return paramMap;
	}

	/**
	 * 判断是否直连银行
	 */
	protected boolean isDirectBankPay(CpsGenMainOrder order) {
		return GatewayChannel.GATEWAY_CHANNEL_01.value.equals(order.getGatewayChannel());
	}

    protected List<AcctBean> getP2PAcctBeans(CpsGenMainOrder order)throws WebException {
        CpsGpContractInfo cpsGpContractInfo = cpsGpContractInfoDAO.getByContractNo(order.getRemark1());
        if(cpsGpContractInfo!=null){
            List<AcctBean> acctBeans = new ArrayList<AcctBean>();
            List<AcctMastBean> accts = acctTransService.getAccounts(cpsGpContractInfo.getExcluCustId());
            for(AcctMastBean bean : accts){
                //p2p充值 显示国付宝普通账户
                if(bean.getProdCode() ==  AcctProd.GNST && StringUtils.equals(order.getGopayIntTxnCd(),IntTxnCd._01300.value)){
                    acctBeans.add(getAcctBean(bean));
                //p2p转账 显示签约的专属账户
                }else if(bean.getProdCode() ==  AcctProd.PPEA && StringUtils.equals(order.getGopayIntTxnCd(),IntTxnCd._01302.value) && StringUtils.equals(cpsGpContractInfo.getExcluAcct(),bean.getAcctId())){
                    acctBeans.add(getAcctBean(bean));
                }
            }
            return acctBeans;
        }
        return null;
    }

    private AcctBean getAcctBean(AcctMastBean bean) throws WebException {
        AcctBean acctBean  = new AcctBean();
        acctBean.setAcctId(bean.getAcctId());
        acctBean.setAmout(new BigDecimal(bean.getAvaAmt()));
        if (StringUtils.isBlank(bean.getAcctName())) {
            CpsAcctProdMast acctProd = cpsAcctProdMastQueryManager.getAcctProd(bean.getProdCode());
            if (null == acctProd) {
                logger.error("账户产品不存在！CpsAcctProdMast not exist!" + bean);
                throw new WebException(ProcCodeConstants.PROC_CODE_100F1002);
            }
            acctBean.setName(acctProd.getProdName());
        } else {
            acctBean.setName(bean.getAcctName());
        }
        return acctBean;
    }

    protected List<AcctBean> getAcctBeans(CpsGenMainOrder order, String custId,AcctProd acctProd) throws WebException {
        List<AcctBean> newAcctList = new ArrayList<AcctBean>();
        List<AcctBean> accts = getAcctBeans(order, custId);
        for(AcctBean bean : accts){
            if(bean.getAcctProd() == acctProd){
                newAcctList.add(bean);
            }
        }

        Collections.sort(newAcctList,new Comparator<AcctBean>() {
            @Override
            public int compare(AcctBean o1, AcctBean o2) {
                return o1.getAcctId().compareTo(o2.getAcctId());
            }
        });

        return newAcctList;
    }

	protected List<AcctBean> getAcctBeans(CpsGenMainOrder order, String custId) throws WebException {
		List<AcctBean> as = new ArrayList<AcctBean>();
		List<AcctMastBean> accts = acctTransService.getAccounts(custId);
		List<String> acctIds = getAcctIds(accts);

		SolutionRequest request = new SolutionRequest();
		request.setAcctId(order.getMainRecvAcct());
		request.setSequence(System.currentTimeMillis());
		request.setTimestamp(new Date());
		LegalObjReq reqData = new LegalObjReq();
		reqData.setIntTxnCd(IntTxnCd.get(order.getGopayIntTxnCd()));
		reqData.setTranLocAcct(order.getMainRecvAcct());
		reqData.setTranObjAccts(acctIds);
		request.setRequest(reqData);
		SolutionResponse resp = legalObjSolutionClient.resolve(request);
		LegalObjRes resData = (null == resp || !resp.isSucceed()) ? null : (LegalObjRes) resp.getResponse();

		Set<String> illegalAccts = (null == resData) ? new HashSet<String>() : new HashSet<String>(resData.getIllegalObjAccts());

		for (AcctMastBean am : accts) {
			AcctBean a = new AcctBean();
			a.setAcctId(am.getAcctId());
			a.setAmout(new BigDecimal(am.getAvaAmt()));
            a.setAcctProd(am.getProdCode());
			if (StringUtils.isBlank(am.getAcctName())) {
				CpsAcctProdMast acctProd = cpsAcctProdMastQueryManager.getAcctProd(am.getProdCode());
				if (null == acctProd) {
					logger.error("账户产品不存在！CpsAcctProdMast not exist!" + am);
					throw new WebException(ProcCodeConstants.PROC_CODE_100F1002);
				}
				a.setName(acctProd.getProdName());
			} else {
				a.setName(am.getAcctName());
			}
			// 将非法交易对方排除掉
			if (!illegalAccts.contains(a.getAcctId())) {
				as.add(a);
			}
		}
		return as;
	}

	private List<String> getAcctIds(List<AcctMastBean> accts) {
		List<String> ss = new ArrayList<String>();
		for (AcctMastBean ab : accts) {
            if(ab.getProdCode() == AcctProd.GNST)
			    ss.add(ab.getAcctId());
		}
		return ss;
	}

	protected static String getRandom(int length) {
		return RandomStringUtils.randomAlphabetic(length);
	}

	protected static String getOrderType(CpsGenMainOrder order) {
		if (IntTxnCd._00200.equals(order.getGopayIntTxnCd())) {
			return "102";
		} else if(isP2P(order)){
            return "107";
        }
        return "101";
	}
    
	/**
	 * 在request中放置一个key - value,同时返回value
	 */
	protected  String setReqAttr(String key, String value) {
		getRequest().getSession().setAttribute(key, value);
		return value;
	}
    /**
     * @param request
     * @param orderId 处理的订单号
     * @return
     */
    protected static String setFormHashValue(HttpServletRequest request,String orderId){
    	if(StringUtils.isBlank(orderId))
    		orderId = "NO_ORDER";
    	String value = new String(Base64.encode(DigestUtil.getDigestData(orderId.concat(getRandom(32)).getBytes(), DigestUtil.SHA1)));
    	
    	request.getSession().setAttribute(KEY_FORM_HASH, value);
    	
    	return value;
    }
    
    protected boolean validateSessionKey(HttpServletRequest request, String formHash) {
    	String sessionCode = (String) request.getSession().getAttribute(KEY_FORM_HASH);
    	if (StringUtils.equals(sessionCode, formHash)) {
    		// 把原来保存的code清空
        	request.getSession().setAttribute(KEY_FORM_HASH, null);
    		return true;
    	} else {
    		return false;
    	}
    }
    

    protected HttpServletRequest getRequest() {
        return ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();
    }
    
	protected String getOrderId() {
		/*String orderId =  (String)getRequest().getSession().getAttribute(GOPAY_ORDER_ID);
		if(StringUtils.isEmpty(orderId) && StringUtils.isNotBlank(getRequest().getParameter(GOPAY_ORDER_ID))){
			orderId = getRequest().getParameter(GOPAY_ORDER_ID);
			getRequest().getSession().setAttribute(GOPAY_ORDER_ID,orderId);
		}*/
		return getRequest().getParameter(GOPAY_ORDER_ID);
	}
	
	protected String getGopayUser() {
		String gopayUser =  (String)getRequest().getSession().getAttribute(CAS_GOPAY_USER);
		if(StringUtils.isEmpty(gopayUser) && StringUtils.isNotBlank(getRequest().getParameter(CAS_GOPAY_USER))){
			gopayUser = getRequest().getParameter(CAS_GOPAY_USER);
			getRequest().getSession().setAttribute(CAS_GOPAY_USER,gopayUser);
		}
		return gopayUser;
	}

	protected void printHeader() {
		HttpServletRequest request = getRequest();

		StringBuffer sb = new StringBuffer();
		sb.append(String.format(" %s=%s %n", "url", request.getRequestURL()));
		sb.append(String.format(" %s=%s %n", "x-forwarded-for", request.getHeader("x-forwarded-for")));
		sb.append(String.format(" %s=%s %n", "x-requested-with", request.getHeader("x-requested-with")));
		sb.append(String.format(" %s=%s %n", "user-agent", request.getHeader("user-agent")));
		sb.append(String.format(" %s=%s %n", "referer", request.getHeader("referer")));
		sb.append(String.format(" %s=%s ", "cookie", request.getHeader("cookie")));
		logger.info("头信息：" + sb);

	}

    protected void printRequest(){
        printRequest("");
    }
	protected void printRequest(String className){
        HttpServletRequest request = getRequest();
        StringBuffer sb = new StringBuffer("-"+className+"-{");
        sb.append("REQUEST HEAD DATA:["+request.getHeader("Referer")+"] [");
        sb.append(RequestUtils.getRemoteRealIpAddr(request) + "] [");
        sb.append(DateUtils.format(new Date(),"yyyy-MM-dd HH:mm:ss") + "] [");
        sb.append(request.getMethod() + "] [");
        sb.append(request.getRequestURI()+"]");
        /**
         * deleted by zyt，此处会输出全卡号，因不好处理，且无用日志，注释掉
         * 2017-2-9
         */
        //logger.info(sb.toString());
        if (request.getParameterNames() != null) {
            sb = new StringBuffer("REQUEST BODY DATA:");
            for (Enumeration<?> enumeration = request.getParameterNames(); enumeration.hasMoreElements();) {
                String eleName = (String) enumeration.nextElement();
                String eleValue = request.getParameter(eleName);
                if(StringUtils.isNotBlank(eleValue) && eleValue.endsWith(".js")){

                }else{
                    if(!StringUtils.equals(eleName,"exCvn2"))//不打印信用卡cvn2
                    	/**
                		 * modified by zyt,日志中的卡号做掩码处理，（因字段中会包含 cardno1 等后面加数字的，所以日志掩码工具会检测不到此类，放到外面处理）
                		 * 2017-2-9
                		 */
                    	if(StringUtils.isNotBlank(eleName) && StringUtils.containsIgnoreCase(eleName, "cardno"))
                    	{
                    		sb.append("[" + eleName + "=" + LoggerMaskUtils.maskString(eleValue) + "] ");
                    	} else if(StringUtils.containsIgnoreCase(eleName, "PassWd")){
                    		//add by zyt，如果是密码，则星号显示
							sb.append("[" + eleName + "=" + "**** ****" + "] ");
						} else {
                    		//modified by zyt, 2017-5-23，检测并对其他敏感字段做掩码
                    		sb.append("[" + eleName + "=" + LoggerMaskUtils.checkAndMaskString(eleName, eleValue) + "] ");
                    	}
                }
            }
            logger.info(sb.toString()+"}");
        }
    }

    /**
     * 校验风控限额
     * @throws WebException
     */
    protected void checkTranAmtLimit() throws GopayException {
        CpsGenMainOrder order =  cpsGeneralMainOrderQueryDAO.find(CpsGenMainOrder.class,getOrderId());
        if(order !=null && StringUtils.isBlank(order.getRelevanceGopayOrderId())){
            TranDirection direction = getTranDirection(order);
            if(direction!=null){
                String acctId = order.getMainRecvAcct();
                if(StringUtils.equals(order.getGopayIntTxnCd(),IntTxnCd._01302.value)){
                    acctId = order.getPayAcct();
                }
                try{
                    transLimitCheckService.checkAmtLimit(acctId,direction,IntTxnCd.get(order.getGopayIntTxnCd()),order.getMerTxnAmt());
                }catch (WebException e){
                    Map<MainOrderField, String> values = new HashMap<MainOrderField, String>();
                    values.put(MainOrderField.TXN_STA_CD, TxnStaCode.TXN_STA_CD_90301.value + "");
                    mainOrderUpdateService.updateMany(order.getGopayOrderId(), values);
                    throw new WebException(e.getErrCode());
                }
            }
        }
    }

    private TranDirection getTranDirection(CpsGenMainOrder order){
        String payChannel = order.getPayChannel();
        TranDirection direction = null;
        if(isInchargeOrder(order) || isP2P(order)){
            if (PayChannel._01.value.equals(payChannel) || PayChannel._03.value.equals(payChannel) || PayChannel._04.value.equals(payChannel)) {
                direction = TranDirection.FROM_C_BANK;
            }else if (PayChannel._51.value.equals(payChannel)) {
                direction = TranDirection.FROM_B_BANK;
            }else if(PayChannel._02.value.equals(payChannel)){
                direction = TranDirection.FROM_C_ACCOUNT;
            }else if(PayChannel._52.value.equals(payChannel)){
                direction = TranDirection.FROM_B_ACCOUNT;
            }
        }
        return direction;
    }

    protected String getLoginEmail(){
        LoginUser loginUser = getLoginUser();
        if(loginUser!=null){
            return loginUser.getTitle();
        }
        return null;
    }

	/**
	 * RIMS风控监控
	 */
	protected void rimsProcess(CpsGenMainOrder order) throws WebException {
        logger.info("rimsProcess start--------orderId:"+order.getGopayOrderId()+" at "+DateUtils.getLocalFullDateTime14());
		//判断是否需要做RIMS风控
		RimsEvaluateParas paras = new RimsEvaluateParas();
		//P2P还款
		if(IntTxnCd._01302.value.equals(order.getGopayIntTxnCd()) && ChildTranType._GP_4.value.equals(order.getChildTranType())){
			List<CpsGenMainOrder> childOrderList = cpsGeneralMainOrderQueryManager.getChildRelevanceGopayOrder(order.getGopayOrderId());
			for(CpsGenMainOrder childOrder:childOrderList){
				paras.putPara(ParaKey.IP_ADDRESS, clientIp(getRequest()));
				paras.putPara(ParaKey.SESSION_ID, getRequest().getSession().getId());
				rimsRemoteService.appendEvaluateParas(order.getGopayIntTxnCd(), childOrder.getGopayOrderId(), paras);
			}
			return;
		}
		if (!isRimsNeededControl(order)) return;

		paras = rimsTransService.initParasFromOrder(order);
		
		if (IntTxnCd._00500.value.equals(order.getGopayIntTxnCd())) {
			if (null != getLoginUser()) {
				//充值付款方和收款方相同.
				paras.putPara(ParaKey.PAY_CUST_ID, order.getMainRecvCustId());
				paras.putPara(ParaKey.CUST_NO, order.getMainRecvCustId());
			}
		}
		paras.putPara(ParaKey.IP_ADDRESS, clientIp(getRequest()));
		paras.putPara(ParaKey.SESSION_ID, getRequest().getSession().getId());
		paras.putPara(ParaKey.ACCT_PRODUCT, order.getMainRecvAcctProdCode());

		AcctMastBean acctMast = null;
		if (StringUtils.isNotBlank(order.getPayAcct())) {
			acctMast = acctTransService.getAccount(order.getPayAcct());
			paras.putPara(ParaKey.PAY_BALANCE, acctMast.getBalAmt().toString());
			paras.putPara(ParaKey.PAY_AVA_BALANCE, acctMast.getAvaAmt().toString());
			paras.putPara(ParaKey.PAY_FRZ_BALANCE, acctMast.getFrezAmt().toString());
		}
		
		if (StringUtils.isNotBlank(order.getMainRecvAcct())) {
			acctMast = acctTransService.getAccount(order.getMainRecvAcct());
			paras.putPara(ParaKey.REC_BALANCE, acctMast.getBalAmt().toString());
		}
//		logger.error("RIMS风控远程调用.BEGIN. " + ToStringBuilder.reflectionToString(paras));
		rimsRemoteService.appendEvaluateParas(order.getGopayIntTxnCd(), order.getGopayOrderId(), paras);
		RimsEvaluateResult result = rimsRemoteService.riskEvaluate(order.getGopayIntTxnCd(), order.getGopayOrderId());
//		logger.error("RIMS风控远程调用.END. " + ToStringBuilder.reflectionToString(result));
		if (RimsEvaluateResultStatus.REJECTED.equals(result.getStatus())) {
			logger.error("RIMS风控拒绝 ！  " + ToStringBuilder.reflectionToString(order));
			throw new WebException(ProcCodeConstants.PROC_CODE_200E6001);
		} else {
//			logger.info("RIMS风控通过 ！  " + ToStringBuilder.reflectionToString(result) + ", " + order.getGopayOrderId());
		}
        logger.info("rimsProcess end--------orderId:"+order.getGopayOrderId()+" at "+DateUtils.getLocalFullDateTime14());
	}
	
	private boolean isRimsNeededControl(CpsGenMainOrder order) {
	    return (
	            IntTxnCd._00100.value.equals(order.getGopayIntTxnCd()) || //直接支付
	            IntTxnCd._00200.value.equals(order.getGopayIntTxnCd()) ||//大宗入金
	            IntTxnCd._00400.value.equals(order.getGopayIntTxnCd()) ||//担保支付申请
	            IntTxnCd._01300.value.equals(order.getGopayIntTxnCd()) ||//专属账户充值
	            IntTxnCd._00500.value.equals(order.getGopayIntTxnCd()) ||//充值
	            (IntTxnCd._01302.value.equals(order.getGopayIntTxnCd()) && ChildTranType._GP_1.value.equals(order.getChildTranType()))//P2P投标
	            );
    }
	
    /**
     * B2B银行客户号支持
     * @param mv
     * @param payChannel
     * @param bankCode
     */
    protected void setB2BBankConfig(ModelAndView mv,PayChannel payChannel,String bankCode)throws WebException{
        if(payChannel != null && payChannel.value == PayChannel._51.value){
            String name = b2bBankConfigService.getB2BConfig(bankCode);
            if(name != null){
                String orderId = (String)(mv.getModel().get("orderId"));
                OrderInfo orderInfo = getOrderInfo(orderId);
                mv.addObject("b2bLabelName",name);
                mv.addObject("order", orderInfo);
                if(StringUtils.equals(orderInfo.getIntTxnCd(),IntTxnCd._00100.toString())){
                    mv.setViewName("/00100/common/b2bbis");
                }else{
                    mv.setViewName("pay/bankPayForBis2");
                }
            }
        }
    }


    protected ModelAndView checkAntiPhish(PayChannelCommand command,String returnUrl) throws GopayException {
		CpsGenMainOrder order = cpsGeneralMainOrderQueryDAO.find(CpsGenMainOrder.class,getOrderId());
		if(order == null)
			throw new WebException(ProcCodeConstants.PROC_CODE_100E5041);
		//防钓鱼校验
		VerifyCodeCheckStatus status = rcsAntiPhishingCheckService.verifyCodeConfig(order.getMerId());
		boolean check = false;
		// PORTAL充值交易不进行反钓鱼页面展示
		if (isInchargeOrder(order)) {
			check =  false;
			return null;
		}
		if (GatewayChannel.GATEWAY_CHANNEL_01.value.equals(order.getGatewayChannel())) {
			check = status.isDirectPayOn();
		} else {// 02，00
			check = status.isUnDirectPayOn();
		}
		String codeServer = (String) getRequest().getSession().getAttribute(KEY_ANTIPHISH_VERIFYCODE);
		if (check) {
			getRequest().getSession().removeAttribute(KEY_ANTIPHISH_VERIFYCODE);
			if (StringUtils.isBlank(codeServer) || !StringUtils.equals(command.getVerifyCode(), codeServer)) {
				OrderInfo orderInfo = getOrderInfo(order.getGopayOrderId());
				// 控制台设置单商户验证码图标的时候，不关心GatewayChannel=01或者02，图标是共用的。
				String logo = rcsAntiPhishingCheckService.getMerLogoUrl(order.getMainRecvCustId(), null);
				String url = StringUtils.isBlank(logo) ? null : CashierConfig.get(CashierConfig.MER_LOGO_URL) + logo;
				return antiPhishPage(getRequest(), orderInfo, url,command,returnUrl);
			}

		}
		return null;
	}


	protected ModelAndView checkAntiPhishForDirect(PayInfoCommand command, String returnUrl) throws GopayException {
		CpsGenMainOrder order = cpsGeneralMainOrderQueryDAO.find(CpsGenMainOrder.class,getOrderId());
		if(order == null)
			throw new WebException(ProcCodeConstants.PROC_CODE_100E5041);
		//防钓鱼校验
		VerifyCodeCheckStatus status = rcsAntiPhishingCheckService.verifyCodeConfig(order.getMerId());
		boolean check = false;
		// PORTAL充值交易不进行反钓鱼页面展示
		if (isInchargeOrder(order)) {
			check =  false;
			return null;
		}
		if (GatewayChannel.GATEWAY_CHANNEL_01.value.equals(order.getGatewayChannel())) {
			check = status.isDirectPayOn();
		} else {// 02，00
			check = status.isUnDirectPayOn();
		}
		String codeServer = (String) getRequest().getSession().getAttribute(KEY_ANTIPHISH_VERIFYCODE);
		if (check) {
			getRequest().getSession().removeAttribute(KEY_ANTIPHISH_VERIFYCODE);
			if (StringUtils.isBlank(codeServer) || !StringUtils.equals(command.getVerifyCode(), codeServer)) {
				OrderInfo orderInfo = getOrderInfo(order.getGopayOrderId());
				// 控制台设置单商户验证码图标的时候，不关心GatewayChannel=01或者02，图标是共用的。
				String logo = rcsAntiPhishingCheckService.getMerLogoUrl(order.getMainRecvCustId(), null);
				String url = StringUtils.isBlank(logo) ? null : CashierConfig.get(CashierConfig.MER_LOGO_URL) + logo;
				return antiPhishPageForDirect(getRequest(), orderInfo, url,command,returnUrl);
			}
		}
		return null;
	}


	private static ModelAndView antiPhishPageForDirect(HttpServletRequest request,OrderInfo orderInfo,String logo,PayInfoCommand command,String returnUrl) {
		ModelAndView mav = new ModelAndView("00100/common/illegalCodeCheck");
		mav.addObject("orderId", orderInfo.getOrderId());
		mav.addObject("order", orderInfo);
		mav.addObject("logo", logo);
		mav.addObject("formhash", setFormHashValue(request,orderInfo.getOrderId()));// 防止hack
		mav.addObject("returnUrl",returnUrl);
		Map<String,Object> pageMap = convertToMap(command);
		pageMap.remove("verifyCode");
		mav.addObject("temp",pageMap);
		return mav;
	}


    private static ModelAndView antiPhishPage(HttpServletRequest request,OrderInfo orderInfo,String logo,PayChannelCommand command,String returnUrl) {
        ModelAndView mav = new ModelAndView("00100/common/illegalCodeCheck");
        mav.addObject("orderId", orderInfo.getOrderId());
        mav.addObject("order", orderInfo);
        mav.addObject("logo", logo);
        mav.addObject("formhash", setFormHashValue(request,orderInfo.getOrderId()));// 防止hack
        mav.addObject("returnUrl",returnUrl);
        if(command instanceof BankPayChannelCommand){//页面跳转，风控导致支付密码无效
            BankPayChannelCommand bpc = (BankPayChannelCommand)command;
            bpc.setAntiPhish("1");
        }
        Map<String,Object> pageMap = convertToMap(command);
        pageMap.remove("verifyCode");
        mav.addObject("temp",pageMap);
        return mav;
    }

    private static Map<String,Object> convertToMap(PayChannelCommand command){
       try{
           String json = JsonUtils.toJson(command);
           return JsonUtils.jsonToMap(json);
       }catch (Exception e){

       }
        return null;
    }

	private static Map<String,Object> convertToMap(PayInfoCommand command){
		try{
			String json = JsonUtils.toJson(command);
			return JsonUtils.jsonToMap(json);
		}catch (Exception e){
			logger.error("", e);
		}
		return null;
	}

    protected void logOut(){
//        SecurityUtils.getSubject().logout();
//        getRequest().getSession().removeAttribute(CAS_GOPAY_USER);
    }
    
    /**
     * 校验当前登录用户是否通过实名认证
     * @param loginUser
     * @throws GopayException
     */
    protected void checkPayCustRealNameCertify(LoginUser loginUser) throws GopayException{
        if (loginUser!=null) {            
            if(StringUtils.isBlank(loginUser.getUser().getCustId())){
                throw new GopayException(ProcCodeConstants.PROC_CODE_100E1109, "客户ID错误");
            }
            GopayAllCustInfo custInfo=allCustInfoQueryDAO.getAllCustInfoByCustId(loginUser.getUser().getCustId());
            if(custInfo==null){
                throw new GopayException(ProcCodeConstants.PROC_CODE_100E2018, "客户不存在或已注销");
            }
            
            if(!("1".equals(custInfo.getIsRealNameCertify())||"2".equals(custInfo.getIsRealNameCertify()))){
                throw new GopayException(ProcCodeConstants.PROC_CODE_100E2006, "未实名认证的用户，请联系客服人员");
            }                
        }
    }
    
    /**
     * G商融通获取商户平台账户
     * @param merId
     * @return
     */
    private AcctMastBean getPTAcctBean(String merId){
    	List<AcctMastBean>  accts = acctTransService.getAccounts(merId);
    	if(accts!=null && accts.size()>0){
    		for(AcctMastBean bean : accts){
        		if(bean.getProdCode() == AcctProd.GTPTZH){
        			return bean;
        		}
        	}
    	}
    	return null;
    }

	@ModelAttribute
	public void installCertLicense(){
		getRequest().setAttribute("certLicense", certLicense);
	}

	/**
	 * 记录密码控件日志
	 * @author <a href="mailto:yhwpeng@126.com">wangdong</a>
	 * @date 2017-01-09 15:21:42
	 */
	public Integer logMicrodone(HttpServletRequest request,String mcryptKey,String scenceCode,String gopayOrderId,String status,UserInfo user){
		String network=request.getParameter("network");
		String disk=request.getParameter("disk");
		String cpu=request.getParameter("cpu");
		String hardList=request.getParameter("hardList");

		String localNetwork="",localDisk="",localCpu="",localHardList="";
		if (StringUtils.isNotEmpty(mcryptKey)){
			localNetwork= AESWithJCE.getResult(mcryptKey, network);
			localDisk= AESWithJCE.getResult(mcryptKey, disk);
			localCpu= AESWithJCE.getResult(mcryptKey, cpu);
			localHardList= AESWithJCE.getResult(mcryptKey, hardList);
		}

		PwdCtrlAttrInfo info = new PwdCtrlAttrInfo(localCpu,localDisk,localHardList);
		if (user!=null){
			info.setOperSource(scenceCode + user.getUserType());
			info.setUserId(user.getUserId());
			info.setCustId(user.getCustId());
		}else{
			info.setOperSource(scenceCode + "99");//99表示无法获取用户类型，异常类型，需要排查
		}
		info.setGopayOrderId(gopayOrderId);
		info.setNetwork(localNetwork);
		info.setGmtCreate(DateUtils.getCurrDate());
		if (status==null){
			info.setStatus("java.lang.NullPointerException");
		}else{
			info.setStatus(status.length() > 400 ? status.substring(0, 400) : status);
		}
		if (request!=null){
			info.setRealIp(RequestUtils.getRemoteRealIpAddr(request));
		}
		logger.info("保存密码控件操作记录，明细：" + ToStringBuilder.reflectionToString(info));
		return pwdCtrlAttrInfoManager.savePwdCtrlAttrInfo(info);
	}
}